package concurrent.sync;

import java.io.ObjectStreamException;


/**
 * volatile的两个作用：
 * 1 线程修改完共享变量之后刷新到内存
 * 2 线程修改完共享变量之后要让其他线程读取的共享变量失效
 */
public class SingleTon {

    public volatile static SingleTon INSTANCE;

    private SingleTon() {}

    public static SingleTon getInstance() {
        if (INSTANCE == null) {
            synchronized(SingleTon.class) {
                if (INSTANCE == null) {
                    INSTANCE = new SingleTon();
                }
            }
        }


        return INSTANCE;
    }

    // 防止反序列化创建新的实例
    private Object readResolve() throws ObjectStreamException {
        return INSTANCE;
    }
}


/**
 * 静态内部类也有着一个致命的缺点，就是传参的问题，由于是静态内部类的形式去创建单例的，故外部无法传递参数进去，例如Context这种参数.
 * 虚拟机会保证一个类的<clinit>()方法在多线程环境中被正确的加锁、同步，如果多个线程同时去初始化一个类，
 * 那么只会有一个线程去执行这个类的<clinit>()方法，其他线程都需要阻塞等待，直到活动线程执行<clinit>()方法完毕
 *
 */
class SingleTon2 {

    private static class SingleHolder {
        private static final SingleTon2 INSTANCE = new SingleTon2();
    }

    public static SingleTon2 getInstance() {
        return SingleHolder.INSTANCE;
    }

    // 静态内部类不需要防止反序列化创建新的实例
}
